// ignore_for_file: depend_on_referenced_packages

import 'dart:async';
import 'dart:convert';

import 'package:audio_service/audio_service.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:audio_session/audio_session.dart';

import 'package:just_audio/just_audio.dart';
import 'package:simple_music_app/core/music_service.dart';
import 'package:simple_music_app/core/utils.dart';
import 'package:simple_music_app/core/models/play_list.dart';

class MusicController extends GetxController {
  final AudioPlayer audioPlayer = AudioPlayer();
  var currentIndex = 100000.obs;
  var currentHash = '';
  var isPlaying = false.obs;

  // 不再需要currentAudioId，使用songId替代
  List<PlayList> storePlaylist = [];

  ConcatenatingAudioSource playlist = ConcatenatingAudioSource(
    children: [],
  );

  @override
  void onInit() async {
    super.onInit();
    SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
      statusBarColor: Colors.black,
    ));
    final session = await AudioSession.instance;
    await session.configure(const AudioSessionConfiguration.music());
    // 配置播放器参数
    audioPlayer.positionStream.listen((position) {
      AppLogger.d('当前播放位置: $position');
    });
    audioPlayer.bufferedPositionStream.listen((buffered) {
      AppLogger.d('当前缓冲进度: $buffered');
    });
    audioPlayer.durationStream.listen((duration) {
      if (kDebugMode && duration != null) {
        AppLogger.d('当前歌曲时长: $duration');
      }
    });

    // 监听播放状态和错误
    audioPlayer.playbackEventStream.listen((event) {
      AppLogger.d('播放状态: ${event.processingState}');
      AppLogger.d('缓冲进度: ${event.bufferedPosition}');

    }, onError: (e, stackTrace) {
      AppLogger.e('播放错误: $e\n堆栈跟踪: $stackTrace');
      try {
        musicFluttertoast('播放失败: ${e.toString()}');
      } catch (e) {
        AppLogger.e('显示错误提示失败: $e');
      }
      audioPlayer.stop().catchError((e) {
        AppLogger.e('停止播放器失败: $e');
      });
    });
  }

  @override
  void onClose() {
    try {
      // 停止播放并释放资源
      audioPlayer.stop();
      audioPlayer.dispose();

      // 释放AudioSession资源
      AudioSession.instance.then((session) {
        session.setActive(false);
      });

      // 清理播放列表
      playlist.clear();
      storePlaylist.clear();

      AppLogger.d('音频资源已完全释放');
    } catch (e, stackTrace) {
      AppLogger.e('资源释放异常: $e\n堆栈跟踪: $stackTrace');
    } finally {
      try {
        super.onClose();
      } catch (e) {
        AppLogger.e('父类onClose调用异常: $e');
      }
    }
  }

  void updateCurrentPlaylist(list) {
    // print('list---- $list');
    playlist = ConcatenatingAudioSource(
      // // 播放下个音频之前加载
      // useLazyPreparation: true,
      // // 定义切换算法
      // shuffleOrder: DefaultShuffleOrder(),
      // 指定播放列表项目
      children: list,
    );
    //  currentIndex.value =0;
  }

  void updateCurrentHash(hash) {
    currentHash = hash;
    update();
  }

  void updatePlayList(List<PlayList> list) {
    storePlaylist = list;
    update();
  }

  Future<void> handleInitPlayList(String songId, int playIndex,
      {BuildContext? context}) async {
    try {
      // 验证参数有效性
      if (songId.isEmpty) throw Exception('无效的歌曲ID');
      if (playIndex < 0 || playIndex >= storePlaylist.length) {
        throw Exception('无效的播放索引: $playIndex');
      }
      // 打印播放请求API
      final parts = songId.split('|');
      final keyword = parts[0];
      final n = parts[1];
      AppLogger.d('🎵 播放请求API: https://api.yyy001.com/api/mgmuisc?msg=$keyword&n=$n&type=json');

      // 获取歌曲信息（20秒超时，支持重试）
      final songInfo = await _fetchSongInfoWithRetry(songId);
      final musicUrl = songInfo['url'] as String?;
      final songInfoData = songInfo['songInfo'] as Map<String, dynamic>;

      // 打印完整API响应
      AppLogger.d('🎵 播放API响应数据:');
      AppLogger.d('┌───────────────────────────────────────');
      AppLogger.d('│ music_url: $musicUrl');
      AppLogger.d('│ songInfo: ${jsonEncode(songInfoData)}');
      AppLogger.d('└───────────────────────────────────────');

      // 验证URL有效性
      if (musicUrl == null || musicUrl.isEmpty) {
        throw Exception('无法获取歌曲播放地址');
      }

      final uri = Uri.tryParse(musicUrl);
      if (uri == null || !uri.hasAbsolutePath || !uri.isAbsolute) {
        throw Exception('无效的音频URL格式: $musicUrl');
      }

      // 准备音频源，支持本地缓存文件
      final isCached = songInfo['isCached'] == true;
      final audioSource = isCached
          ? AudioSource.file(
              songInfo['url'],
              tag: MediaItem(
                id: songInfoData['id'] ?? storePlaylist[playIndex].songId,
                title: songInfoData['title'] ?? storePlaylist[playIndex].songName,
                artUri: Uri.parse(
                    songInfoData['cover'] ?? storePlaylist[playIndex].coverUrl),
                album: songInfoData['singer'] ?? storePlaylist[playIndex].artist,
                extras: {'isCached': true},
              ),
            )
          : AudioSource.uri(
              uri,
              tag: MediaItem(
                id: songInfoData['id'] ?? storePlaylist[playIndex].songId,
                title: songInfoData['title'] ?? storePlaylist[playIndex].songName,
                artUri: Uri.parse(
                    songInfoData['cover'] ?? storePlaylist[playIndex].coverUrl),
                album: songInfoData['singer'] ?? storePlaylist[playIndex].artist,
                extras: {'isCached': false},
              ),
            );

      // 显示缓存状态
      if (context != null && context.mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(isCached ? '正在播放本地缓存' : '正在在线播放'),
            duration: const Duration(seconds: 2),
          ),
        );
      }

      // 安全设置音频源
      await _safeSetAudioSource(audioSource, playIndex);
      // 实时缓冲监听和渐进式播放
      final completer = Completer<void>();
      bool isPlayingStarted = false;

      final subscription =
          audioPlayer.playbackEventStream.listen((event) async {
        try {
          if (!isPlayingStarted) {
            final buffered = event.bufferedPosition;
            final total = event.duration ?? Duration.zero;

            AppLogger.d('🎵 缓冲检查: $buffered / $total');

            // 当缓冲超过3秒或完整缓冲时开始播放
            if (buffered.inSeconds > 3 || buffered >= total) {
              await audioPlayer.play();
              isPlayingStarted = true;
              completer.complete();
              AppLogger.d('🎵 渐进式播放启动成功');
            }
          }
        } catch (e, stackTrace) {
          AppLogger.e('渐进式播放错误: $e\n$stackTrace');
          completer.completeError(e);
        }
      }, onError: (e, stackTrace) {
            AppLogger.e('🎵 播放事件监听错误: $e\n$stackTrace');
        completer.completeError(e);
      });

      // 设置总超时30秒
      try {
        await completer.future.timeout(Duration(seconds: 30));
      } on TimeoutException {
        subscription.cancel();
        throw Exception('播放超时\n'
            '当前缓冲: ${audioPlayer.bufferedPosition.inSeconds}s');
      } catch (e) {
        subscription.cancel();
        throw Exception('播放启动失败: $e\n'
            '缓冲进度: ${audioPlayer.bufferedPosition.inSeconds}s\n'
            '可能原因:\n'
            '1. 网络连接不稳定\n'
            '2. 音频文件过大\n'
            '3. 服务器响应缓慢');
      } finally {
        subscription.cancel();
      }

      // 强制更新播放状态
      isPlaying.value = true;
      currentIndex.value = playIndex;
      currentHash = songId;
      update(); // 立即触发UI更新

      // 更新存储的播放列表信息
      storePlaylist[playIndex] = PlayList(
        songId: songInfoData['id'] ?? storePlaylist[playIndex].songId,
        songName: songInfoData['title'] ?? storePlaylist[playIndex].songName,
        artist: songInfoData['singer'] ?? storePlaylist[playIndex].artist,
        coverUrl: songInfoData['cover'] ?? storePlaylist[playIndex].coverUrl,
        musicUrl: musicUrl,
      );
      update(); // 再次确保UI更新
    } on TimeoutException {
      throw Exception('操作超时，请检查网络连接');
    } catch (e) {
      // 确保停止播放器
      await _safeStopPlayer();

      // 显示错误提示
      if (context != null && context.mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
              content: Text('播放失败: ${e.toString().replaceAll('\n', ' ')}')),
        );
      }
      rethrow;
    }
  }

  Future<void> _safeSetAudioSource(AudioSource source, int playIndex) async {
    try {
      // 先停止当前播放
      if (audioPlayer.playing) {
        await audioPlayer.stop();
      }

      // 设置新的音频源（20秒超时）
      await audioPlayer
          .setAudioSource(
            ConcatenatingAudioSource(children: [source]),
            initialIndex: 0,
            initialPosition: Duration.zero,
          )
          .timeout(Duration(seconds: 20));
    } catch (e) {
      await _safeStopPlayer();
      throw Exception('设置音频源失败: $e');
    }
  }

  void pause() {
    audioPlayer.pause();
    isPlaying.value = false;
  }

  void resume() {
    audioPlayer.play();
    isPlaying.value = true;
  }

  void seek(Duration position) {
    audioPlayer.seek(position);
  }

  void seekToNext() async {
    if (currentIndex.value < playlist.children.length - 1) {
      currentIndex.value += 1;

      String newSongId = storePlaylist[currentIndex.value].songId;
      await handleInitPlayList(newSongId, currentIndex.value);
    } else {
      musicFluttertoast('已经是最后一首');
    }
  }

  void seekToPrevious() async {
    if (currentIndex.value > 0) {
      currentIndex.value -= 1;
      try {
        String newSongId = storePlaylist[currentIndex.value].songId;
        await handleInitPlayList(newSongId, currentIndex.value);
      } catch (e) {
        AppLogger.e('切换上一首失败: $e');
        musicFluttertoast('切换失败');
      }
    } else {
      musicFluttertoast('已经是第一首');
    }
  }

  Future<void> play(int index, String songId, {BuildContext? context}) async {
    AppLogger.d('🎵 播放请求: $songId');
    AppLogger.d('🎵 当前播放列表状态:');
    AppLogger.d('┌───────────────────────────────────────');
    AppLogger.d('│ storePlaylist长度: ${storePlaylist.length}');
    AppLogger.d('│ 请求索引: $index');
    AppLogger.d('│ 当前索引: ${currentIndex.value}');
    AppLogger.d('└───────────────────────────────────────');

    if (currentIndex.value == index) {
      if (!isPlaying.value) {
        resume(); // 如果当前歌曲没有播放，则调用 resume
      }
      if (songId != currentHash) {
        try {
          currentIndex.value = index;
          await handleInitPlayList(songId, currentIndex.value,
              context: context);
          isPlaying.value = true;
        } on PlayerException {
          musicFluttertoast('播放失败');
        }
      }
      return; // 直接返回，不重新播放
    }
    try {
      currentIndex.value = index;
      await handleInitPlayList(songId, currentIndex.value, context: context);
      isPlaying.value = true;

      // 显示缓存状态
      if (context != null && context.mounted) {
        final songInfo = await fetchSongInfo(songId);
        final isCached = songInfo['isCached'] == true;
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(isCached ? '已缓存到本地' : '正在缓存歌曲...'),
            duration: const Duration(seconds: 2),
          ),
        );
      }
    } on PlayerException {
      musicFluttertoast('播放失败');
    }
  }

  void playerStateStream() async {
    audioPlayer.currentIndexStream.listen((playerState) async {
      AppLogger.d('playerState: $playerState');
      if (playerState != null) {
        if (playerState > currentIndex.value + 1) {
          return;
        } else {
          currentIndex.value = playerState;
          String newSongId = storePlaylist[currentIndex.value].songId;
          await handleInitPlayList(newSongId, playerState,
              context: Get.context);
        }
      }
    });
  }

  Future<void> _safeStopPlayer() async {
    try {
      if (audioPlayer.playing) {
        await audioPlayer.stop();
      }
      await audioPlayer.dispose();
    } catch (e) {
      AppLogger.e('安全停止播放器失败', e);
      rethrow;
    }
  }

  Future<Map<String, dynamic>> _fetchSongInfoWithRetry(String songId) async {
    const maxRetries = 3;
    const timeoutDuration = Duration(seconds: 20);

    for (int attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        AppLogger.d('🎵 尝试获取歌曲信息: $songId');
        return await fetchSongInfo(songId).timeout(timeoutDuration);
      } catch (e) {
        if (attempt == maxRetries) rethrow;
        await Future.delayed(Duration(seconds: attempt * 2));
      }
    }
    throw Exception('获取歌曲信息失败');
  }
}
